package com.jack.thinking.java._22.swing.concurrent;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.ProgressMonitor;
import javax.swing.SwingUtilities;

import com.utils.SwingConsole;
import com.utils.TaskManager;

public class MonitorLongRunningCallable extends JFrame{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private JButton b1 = new JButton("Start Long Running Task");
	private JButton b2 = new JButton("End Long Running Task");
	private JButton b3 = new JButton("Get results");
	
	private TaskManager<String, MonitoredCallable> manager = new TaskManager<>();
	public MonitorLongRunningCallable() {
		b1.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				MonitoredCallable task = new MonitoredCallable(new ProgressMonitor(MonitorLongRunningCallable.this, "Long-Running Task", "", 0, 0));
				manager.add(task);
				System.out.println(task + " added to the queue");
			}
		});
		
		b2.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				for(String result : manager.purge()) {
					System.out.println(result);
				}
			}
		});
		
		b3.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				for(String result : manager.getResults()) {
					System.out.println(result);
				}
			}
		});
		
		setLayout(new FlowLayout());
		add(b1);
		add(b2);
		add(b3);
	}
	
	public static void main(String[] args) {
		SwingConsole.run(new MonitorLongRunningCallable(), 200, 500);
	}
}

class MonitoredCallable implements Callable<String>{
	private static int counter = 0;
	private final int id = counter++;
	private final ProgressMonitor monitor;
	private final static int MAX = 8;
	
	
	public MonitoredCallable(ProgressMonitor monitor) {
		super();
		this.monitor = monitor;
		this.monitor.setNote(toString());
		this.monitor.setMaximum(MAX - 1);
		this.monitor.setMillisToPopup(500);
	}


	@Override
	public String call() {
		System.out.println(this + " started");
		try {
			for(int i =0; i < MAX; i++) {
				TimeUnit.MILLISECONDS.sleep(500);
				if(monitor.isCanceled()) {
					Thread.currentThread().interrupt();
				}
				final int progress = i;
				//他是一个单独的任务， 因此不应该尝试直接控制UI，前面的列子 没有使用， 是因为没有涉及到组件的更新。
				SwingUtilities.invokeLater(new Runnable() {         

					@Override
					public void run() {
						monitor.setProgress(progress);
					}
					
				});
			}
		} catch (InterruptedException e) {
			monitor.close();
			System.out.println(this + " interrupted");
			return  "Result: " + this + " interrupted";
		}
		 
		System.out.println(this + " completed");
		return "Result:  " + this + " completed";
	}
	
	@Override
	public String toString() {
		return "Task " + id;
	}
	
}